#include "Voter.h"

#include <iostream>
#include <fstream>

using namespace std;

Voter::Voter(void)
{
}

Voter::~Voter(void)
{
}

Voter* Voter::newInstance(std::string _insName, MemoryManager *_memM)
{
    //TODO
    Voter* ret = _memM->newT(ret);
    return ret;
}

VOID Voter::deleteInstance(INOUT VOID* _ptr, IN STRING _insName, IN MemoryManager* _memM)
{
    //TODO
    _memM->deleteT((Voter*)_ptr);
}

VOID Voter::regLogger(IN Logger* _logger)
{
    m_Logger = _logger;
}

VOID Voter::regMemoryManager(IN MemoryManager* _mem)
{
    m_MemoryManager = _mem;
}

//#define _DEBUG_VOTER
#ifdef _DEBUG_VOTER
#endif //#ifdef _DEBUG_VOTER


vector<UINT32> Voter::vote(IN UINT32 _nlabel, IN vector<STRING>& _tmpFile)
{
    vector<vector<UINT32> > count;

#ifdef _DEBUG_VOTER
    vector<DOUBLE**> vmatrix;
#endif //#ifdef _DEBUG_VOTER

    UINT32 id = 0;
    for (UINT32 ipos = 0; ipos < _nlabel - 1; ++ipos)
    {
        for (UINT32 ineg = ipos + 1; ineg < _nlabel; ++ineg)
        {

#ifdef _DEBUG_VOTER
            cout << ipos << " vs " << ineg << " :" << _tmpFile[id] << endl;
#endif //#ifdef _DEBUG_VOTER          

            ifstream fin(_tmpFile[id].c_str());
            {
                DOUBLE val;
                UINT32 line = 0;
                while (fin >> val)
                {
                    if (id == 0)
                    {
                        vector<UINT32> cc;
                        cc.resize(_nlabel, 0);
                        count.push_back(cc);

#ifdef _DEBUG_VOTER
                        DOUBLE** matrix = new DOUBLE*[_nlabel];
                        for (UINT32 di = 0; di < _nlabel; ++di)
                        {
                            matrix[di] = new DOUBLE[_nlabel];
                            matrix[di][di] = 0;
                        }
                        vmatrix.push_back(matrix);
#endif //#ifdef _DEBUG_VOTER
                    }

                    if (val >= 0.5)
                    {
                        ++count[line][ipos];
                    }
                    else 
                    {
                        ++count[line][ineg];
                    }

#ifdef _DEBUG_VOTER
                    vmatrix[line][ipos][ineg] = val;
                    vmatrix[line][ineg][ipos] = 1 - val;
#endif //#ifdef _DEBUG_VOTER

                    ++line;
                }
            }
            fin.close();
            ++id;
        }        
    }

#ifdef _DEBUG_VOTER
    ofstream dout("debug_voter.out");
    {
        for (UINT32 i = 0; i < vmatrix.size(); ++i)
        {
            dout << i << " : " << endl;
            for (UINT32 x = 0; x < _nlabel; ++x)
            {
                for (UINT32 y = 0; y < _nlabel; ++y)
                {
                    dout << vmatrix[i][x][y] << " \t ";
                }
                dout << endl;
                delete[] vmatrix[i][x];
            }
            delete[] vmatrix[i];
        }
    }
    dout.close();
#endif //#ifdef _DEBUG_VOTER

    vector<UINT32> ret;
    for (UINT32 i = 0; i < count.size(); ++i)
    {
        UINT32 mmax = 0, mj = 0;
        for (UINT32 j = 0; j < _nlabel; ++j)
        {
            if (count[i][j] > mmax)
            {
                mmax = count[i][j];
                mj = j;
            }
        }
        ret.push_back(mj);
    }
    return ret;
}


#ifdef _DEBUG_VOTER
#undef _DEBUG_VOTER //#define _DEBUG_VOTER
#endif //#ifdef _DEBUG_VOTER